/**
 * 
 */
package badugi;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author aleks
 * @version 0.1
 * The main class of the server. There parameters of the game are taken from terminal.
 */
public class Server {

	private static Room activeRoom;
	private static ServerSocket serwer;
	private static int port = 4444;

	/**
	 * @param args arguments of calling program.
	 */
	public static void main(String[] args) {
		if (args.length == 4) {
			try {
				int nrOfPlayers = Integer.parseInt(args[0]);
				int nrOfTokens = Integer.parseInt(args[1]);
				int smallBlindValue = Integer.parseInt(args[2]);
				int bigBlindValue = Integer.parseInt(args[3]);
				//Utworzenie serwera
				try {
					listen(nrOfPlayers, nrOfTokens, smallBlindValue, bigBlindValue);
				}
				catch (RoomException e) {
					System.out.println(e.getMessage());
				}
			}
			catch (NumberFormatException e) {
				System.out.println("Exception in parameters: probably some of them are not an integer");
			}
		}
		else {
			System.out.println("Invalid number of parameters. NumberOfPlayers NumberOfTokens, SmallBlind, BigBlind");
		}

	}
	
	/**
	 * @author aleks
	 * Method which listen and wait for clients. Client will be added only if he is needed.
	 */
	private static void listen(int nrOfPlayers, int nrOfTokens, int smallBlindValue, int bigBlindValue) throws RoomException {				
		activeRoom = new Room(nrOfPlayers, nrOfTokens, smallBlindValue, bigBlindValue);
		System.out.println("+++Badugi Room (Server) ver. 0.1+++\nWelcome!\nIt's a server for " + nrOfPlayers);
		try {
			serwer = new ServerSocket(port);
			System.out.println("I am listening on the port " + port);
			ServerThread[] sequence = new ServerThread[nrOfPlayers];
			try
			{
				int counter=0;
				boolean isRoomRun = false;
				while (true) {
					Socket client = serwer.accept();
					for (int i = 0; i < sequence.length; i++) {
						if (sequence[i] != null && !sequence[i].isAlive()) {
							sequence[i] = null;
							counter--;
							if (counter < 0) counter = 0;
							System.out.println("Some of the player was disconnected.");
						}
					}
					if (counter < nrOfPlayers) {
						if (!isRoomRun) {
							System.out.println("A client trying to connect");
							PrintWriter out = new PrintWriter(client.getOutputStream(), true);
							
							sequence[counter] = new ServerThread(nrOfPlayers, nrOfTokens, smallBlindValue, bigBlindValue, client, out, counter, sequence, activeRoom);
							out.println("<" + nrOfPlayers + "><01><" + counter + "," + nrOfPlayers + "," + nrOfTokens + "," + smallBlindValue + "," + bigBlindValue + ">");
							sequence[counter].start();
							counter++;
							if (counter == nrOfPlayers) {
								activeRoom.setSequence(sequence);
								isRoomRun = true;
								activeRoom.start();
							}
						}
						else {
							int whichIsDeadAndFree = 0;
							for (int i = 0; i < sequence.length; i++) {
								if ( sequence[i] == null ) {
									whichIsDeadAndFree = i;
									break;
								}
							}
							synchronized (serwer) {
								System.out.println("A client trying to connect");
								PrintWriter out = new PrintWriter(client.getOutputStream(), true);
								sequence[whichIsDeadAndFree] = new ServerThread(nrOfPlayers, nrOfTokens, smallBlindValue, bigBlindValue, client, out, counter, sequence, activeRoom);
								out.println("<" + nrOfPlayers + "><01><" + counter + "," + nrOfPlayers + "," + nrOfTokens + "," + smallBlindValue + "," + bigBlindValue + ">");
								sequence[whichIsDeadAndFree].start();
								counter++;
							}
							if (!activeRoom.isAlive()) {
								if (counter == nrOfPlayers) {
									System.out.println("S: I have to create new Room.");
									activeRoom = new Room(nrOfPlayers, nrOfTokens, smallBlindValue, bigBlindValue);
									activeRoom.setSequence(sequence);
									isRoomRun = true;
									activeRoom.start();
								}
							}
						}

					}
					else {
						PrintWriter out = new PrintWriter(client.getOutputStream(), true);
						out.println("<" + nrOfPlayers + "><30><" + "We've all players now. Try later." + ">");
						out.close();
						client.close();
					}
				}
			} 
			catch (IOException e) {
				System.out.println("Accept failed: 4444");
			}	
		}
		catch (IOException e) {
			System.out.println("I can not listen on that port " + port);
		}
	}

}
